from spConstants import *
from eDIP43A_Exceptions import NotImplementedException

class eDIP43A_Display():
    """ 
    """

    def __init__(self, on_bargraph=None, on_touch=None, on_input=None):
        print "constructor for Display"
        self.on_bargraph = on_bargraph
        self.on_touch = on_touch
        self.on_input = on_input
        pass

    #------------------ Private Functions
    def __eDIP_command(self, data, data1=None, data2=None, data3=None, data4=None, data5=None, data6=None):
        """
        """
        buf = bytearray()

        buf.append(ESC)
        for x in data:
            buf.append(x) 
        if(data1!=None):
            buf.append(data1)
        if(data2!=None):
            buf.append(data2)
        if(data3!=None):
            buf.append(data3)
        if(data4!=None):
            buf.append(data4)
        if(data5!=None): 
            buf.append(data5)
        if(data6!=None): 
            buf.append(data6)	
        return buf

    def __eDIP_string(self, data, string, x=None, y=None):
        """
        """
        buf = bytearray() 	#MAX_STring is definied in display.h

        buf.append(ESC)
        for i in data:
            buf.append(i)
        if(x!=None):
            buf.append(x&0x00FF) 		#low byte of x-position
            buf.append((x>>8)&0x00FF)		#high-byte of x-position
        if(y!=None): 
            buf.append(y&0x00FF)		#low-byte of y-position
            buf.append((y>>8)&0x00FF)		#high-byte of y-positon 

        length = 0                              #be sure, that string is not too long and
        for x in string:			#store string    
            buf.append(x)
            length=length+1
            if(length>MAX_STRING):
                break

        buf.append(0)				#Close string	
        return buf

    def __eDIP_draw(self, data, x1=None, y1=None, x2=None, y2=None, x3=None, y3=None):
        """
        """
        buf = bytearray()

        buf.append(ESC)
        for x in data:
            buf.append(x)
        if(x1!=None):
            buf.append(x1 & 0x00FF)
            buf.append((x1 >> 8) & 0x00FF)
        if(y1!=None):
            buf.append(y1 & 0x00FF)
            buf.append((y1>>8)&0x00FF)
        if(x2!=None):
            buf.append(x2 & 0x00FF)
            buf.append((x2>>8) & 0x00FF)
        if(y2!=None):
            buf.append(y2&0x00FF)
            buf.append((y2>>8)&0x00FF)
        if(x3!=None):	
            buf.append(x3 & 0x00FF)
            buf.append((x3>>8)&0x00FF)
        if(y3!=None):
            buf.append(y3&0x00FF)
            buf.append((y3>>8)&0x00FF)

        return buf

    def __eDIP_bargraph(self, data, nr, x1, y1, x2, y2, sv, ev, type):
        """
        """
        buf = bytearray()

        buf.append(ESC)
        for x in data:
            buf.append(x)

        buf.append(nr)	
        buf.append(x1&0x00FF)		    #xstart low-byte
        buf.append((x1>>8)&0x00FF)	    #xstart high-byte
        buf.append(y1&0x00FF)		    #ystart low-byte
        buf.append((y1>>8)&0x00FF)	    #ystart high-byte
        buf.append(x2&0x00FF)		    #xend low-byte
        buf.append((x2>>8)&0x00FF)	    #xend high-byte
        buf.append(y2&0x00FF0)		    #yend low-byte
        buf.append((y2>>8)&0x00FF)	    #yend high-byte
        buf.append(sv)
        buf.append(ev)
        buf.append(type)	
        return buf

    def __eDIP_touch(self, data, string, dc, uc, x1, y1, x2=None, y2=None):
        """
        """
        buf = bytearray()

        buf.append(ESC)
        for x in data:
            buf.append(x)

        buf.append(x1&0x00FF)		#xstart low-byte
        buf.append((x1>>8)&0x00FF)	#xstart high-byte
        buf.append(y1&0x00FF)		#ystart low-byte
        buf.append((y1>>8)&0x00FF)	#ystart high-byte
        buf.append(x2&0x00FF)		#xend low-byte
        buf.append((x2>>8)&0x00FF)	#xend high-byte
        buf.append(y2&0x00FF)		#yend low-byte
        buf.append((y2>>8)&0x00FF)	#yend high-byte
        buf.append(dc)			#downcode
        buf.append(uc)			#upcode

        length = 0                              #be sure, that string is not too long and
        for x in string:			#store string    
            buf.append(x)
            length=length+1
            if(length>MAX_STRING):
                break
        buf.append(0)

        return buf


    def DecodeBuffer(self, result):
        """ Decode content received from buffer
        """
        #if(not result):
            #return
        
        i = 0;
        while(i < len(result)):
            if(chr(result[i])==ESC):
                if(chr(result[i+1])=='A'):
                    if(result[i+2]==1):
                        #print ("Button code no: " + str(result[i+3]))
                        if(self.on_touch):
                            self.on_touch(result[i+3])
                        i+=3
                    else:
                        i+=1
                        continue                    
                elif(chr(result[i+1])=='B'):
                    if(result[i+2]==2):
                        #print ("Bargraph no: " + str(result[i+3]) + " Value: "+ str(result[i+4]))
                        if(self.on_bargraph):
                            self.on_bargraph(result[i+3], result[i+4])
                        i+=4
                    else:
                        i+=1
                        continue
                elif(chr(result[i+1])=='B'):
                    pass                  
                elif(chr(result[i+1])=='F'):
                    pass                  
                elif(chr(result[i+1])=='P'):
                    if(result[i+2]==1):
                        #print ("Value: " + str(bin(result[i+3])))
                        if(self.on_input):
                            self.on_input(result[i+3])
                        i+=3
                        continue
                    else:
                        i+=1
                        continue

                elif(chr(result[i+1])=='M'):
                    pass                                    
                elif(chr(result[i+1])=='H'):
                    pass                                                      
                elif(chr(result[i+1])=='X'):
                    pass                                                                        
                elif(chr(result[i+1])=='G'):
                    pass
                elif(chr(result[i+1])=='Y'):
                    pass                                                                                                            
                elif(chr(result[i+1])=='D'):
                    pass
                elif(chr(result[i+1])=='W'):
                    pass
                elif(chr(result[i+1])=='V'):
                    pass                                                                                                            
                elif(chr(result[i+1])=='J'):
                    pass
                elif(chr(result[i+1])=='G'):
                    pass
                elif(chr(result[i+1])=='I'):
                    pass                                                                                                            
                elif(chr(result[i+1])=='U'):
                    pass                                                                                                                                                
            else:
                #log.msg("Discarted data: " + str(result[i]))
                i+=1



    #----------------------------------------------------------------------
    def send_Command(self, buffer, payload=False, protocol=False):
        """
        Define this method in the inherited class
        """

        raise NotImplementedException("Method not implemented by derived class")


    #------------------ Terminal functions -----------------
    def eDIP_TA(self):
        """
        #TA=Terminal off: #TA  (switch Terminal off outputs are ignored)
        """
        return self.__eDIP_command("TA")	

    def eDIP_TE(self):
        """
        #TE=Terminal on: #TE  (switch Terminal on)	
        """
        return self.__eDIP_command("TE")	 

    #------------------ Graphic commands -------------------

    #------------------ Display commands (effect entire display)

    def eDIP_FD(self, fg, bg):
        """
        #FD=Set display color: 
        #FD fg,bg  (foreground color fg=1..32; background color bg=1..32)	
        """
        return self.__eDIP_command("FD", fg, bg)	

    def eDIP_DO(self, n1):
        """
        #DO=Set display orientation:
        #DO n1  (Display orientation n1: 0=0; 1=90; 2=180; 3=270)
        """
        return self.__eDIP_command("DO",n1)		

    def eDIP_DL(self):
        """
        #DL=Delete display: 
        #DL  (Fill display contents with display background color)	
        """
        return self.__eDIP_command("DL")		

    def eDIP_DS(self):
        """
        #DS=Fill display: 
        #DS  (Fill display contents with display foreground color)
        """
        return self.__eDIP_command("DS")

    def eDIP_DF(self, c):
        """
        #DF=Fill display with color: 
        #DF fg  (Fill display contents with color fg=1..32)
        """
        return self.__eDIP_command("DF", c)		

    def eDIP_DI(self):
        """
        #DI=Invert display: 
        #DI  (Invert display contents / invert all pixels)
        """
        return self.__eDIP_command("DI")		

    #------------------------ Oututting strings

    def eDIP_FZ(self, fg, bg):
        """
        #FZ=Set string color: 
        #FZ fg,bg  (fg=foreground color; bg=background color; fg/bg=palette 1..32 or 0=transparent)
        """
        return self.__eDIP_command("FZ", fg, bg)	

    def eDIP_ZF(self, n1):
        """
        #ZF=Set font: 
        #ZF n1  (Set font with the number n1=0..255)
        """
        return self.__eDIP_command("ZF",n1)		

    def eDIP_ZZ(self, x, y):	
        """
        #ZZ=Font zoom factor: 
        #ZZ n1,n2  (n1=X-Zoom factor 1x..8x;  n2=Y-Zoom factor 1x..8x)
        """
        return self.__eDIP_command("ZZ", x, y)	

    def eDIP_ZY(self, lr, tb):
        """
        #ZY=Add char width/height: 
        #ZY n1,n2  (adds n1=0..15 dots at left/right and n2=0..15 dots at top/bottom of each character)	
        """
        return self.__eDIP_command("ZY", lr, tb)    

    def eDIP_ZJ(self, x):
        """
        #ZJ=Space width: 
        #ZJ n1  (n1=0: use original space from font; n1=1: same width as numbers; n1>=2: width in dots)	
        """
        return self.__eDIP_command("ZJ",x);		

    def eDIP_ZW(self, x):
        """
        #ZW=Text angle: 
        #ZW n1  (Text output angle n1: 0=0; 1=90; 2=180; 3=270)
        """
        return self.__eDIP_command("ZW",x);		

    def eDIP_ZL(self,x,y,string):
        """
        #ZL=Output string left justified: 
        #ZL xx1,yy1,"Text"  (A string is output to xx1,yy1 several lines are separated by '|')	
        """
        return self.__eDIP_string("ZL", string, x, y)  

    def eDIP_ZC(self,x,y,string):	
        """
        #ZC=Output string centered: #ZC xx1,yy1,"Text"  (A string is output to xx1,yy1 several lines are separated by '|')
        """
        return self.__eDIP_string("ZC", string, x, y)  

    def eDIP_ZR(self, x,y,string):
        """
        # #ZR=Output string right justified: 
        #ZR xx1,yy1,"Text"  (A string is output to xx1,yy1 several lines are separated by '|')
        """
        return self.__eDIP_string("ZR", string, x, y)   

    def eDIP_ZT(self, string):	
        """
        #ZT=String for terminal: 
        #ZT "Text"  (Command for outputting a string in a macro to the terminal)	
        """
        return self.__eDIP_string("ZT",string)		 


    #------------------------- draw straight lines and points
    def eDIP_FG(self,fg,bg):	
        """
        #FG=Set line color: 
        #FG fg,bg  (foreground/line color fg=1..32; pattern background color bg=1..32 or 0=transparent)	
        """
        return self.__eDIP_command("FG", fg, bg)	

    def eDIP_GR(self,x1,y1,x2,y2):
        """
        #GR=Draw rectangle: 
        #GR xx1,yy1,xx2,yy2  (Draw four straight lines as a rectangle from xx1,yy1 to xx2,yy2)
        """
        return self.__eDIP_draw("GR", x1, y1, x2, y2) 

    def eDIP_GD(self,x1,y1,x2,y2):
        """
        #GD=Draw straight line: 
        #GD xx1,yy1,xx2,yy2  (Draw straight line from xx1,yy1 to xx2,yy2)
        """
        return self.__eDIP_draw("GD", x1, y1, x2, y2) 

    def eDIP_GW(self,x1,y1):			
        """
        #GW=Continue straight line: 
        #GW xx1,yy1  (Draw a straight line from last end point to xx1,yy1)
        """	
        return self.__eDIP_draw("GW", x1, y1)   

    def eDIP_GP(self,x1,y1):			
        """
        #GP=Draw point: 
        #GP xx1,yy1  (Set one dot at coordinates xx1,yy1)	
        """
        return self.__eDIP_draw("GP", x1, y1)   

    def eDIP_GZ(self,n1, n2):		
        """"
        # #GZ=Point size/line thickness: 
        #GZ n1,n2  (n1=X-dotsize 1..15;  n2=Y-dotsize 1..15)
        """	
        return self.__eDIP_command("GZ", n1, n2)	

    def eDIP_GM(self,n1):
        """
        #GM=Line pattern: 
        #GM n1  (n1=0: no pattern, draw a solid line; n1=1..255: use a pattern for points/lines)
        """
        return self.__eDIP_command("GM",n1);		

    #------------------------- change draw rectangular areas

    def eDIP_RL(self,x1,y1,x2,y2):
        """
        #RL=Delete area: 
        #RL xx1,yy1,xx2,yy2  (Fill an area from xx1,yy1 to xx2,yy2 with display background color)
        """
        return self.__eDIP_draw("RL", x1, y1, x2, y2)	 

    def eDIP_RS(self,x1,y1,x2,y2):
        """
        #RS=Fill area: 
        #RS xx1,yy1,xx2,yy2  (Fill an area from xx1,yy1 to xx2,yy2 with display foreground color)
        """
        return self.__eDIP_draw("RS", x1, y1, x2, y2)	 

    def eDIP_RF(self,x1,y1,x2,y2,n1):
        """
        #RF=Fill area with color: 
        #RF xx1,yy1,xx2,yy2,fg  (Fill an area from xx1,yy1 to xx2,yy2 with color fg=1..32)
        """
        return self.__eDIP_draw("RF", x1, y1, x2, y2, n1)

    def eDIP_RI(self,x1,y1,x2,y2):
        """
        #RI=Invert area: 
        #RI xx1,yy1,xx2,yy2  (Invert an area from xx1,yy1 to xx2,yy2 / invert all pixels)
        """
        return self.__eDIP_draw("RI", x1, y1, x2, y2)	 

    def eDIP_RC(self,x1,y1,x2,y2,x3,y3):
        """
        #RC=Copy area: 
        #RC xx1,yy1,xx2,yy2,xx3,yy3  (copy the area from xx1,yy1 to xx2,yy2 to new upper left corner xx3,yy3)
        """
        return self.__eDIP_draw("RC", x1, y1, x2, y2, x3, y3) 

    def eDIP_FM(self,fg,bg):
        """
        #FM=Set pattern color: 
        #FM fg,bg  (fg=foreground color; bg=background color; fg/bg=palette 1..32 or 0=transparent)
        """
        return self.__eDIP_command("FM", fg, bg)

    def eDIP_RM(self,x1,y1,x2,y2,n1):	
        """
        #RM=Area with fill pattern: 
        #RM xx1,yy1,xx2,yy2,n1  (Draw an area from xx1,yy1 to xx2,yy2 with pattern n1)
        """
        return self.__eDIP_draw("RM", x1, y1, x2, y2, n1)

    def eDIP_RO(self,x1,y1,x2,y2,n1):	
        """
        #RO=Draw box: 
        #RO xx1,yy1,xx2,yy2,n1  (Draw a rectangle xx1,yy1 to xx2,yy2 with fill pattern n1)
        """
        return self.__eDIP_draw("RO", x1, y1, x2, y2, n1)

    def eDIP_FR(self,c1,c2,c3):		
        """
        #FR=Set border colors: 
        #FR f1,f2,f3  (f1..f3=1..32 or 0=transparent; f1=frame outside; f2=frame inside; f3=filling)
        """
        return self.__eDIP_command("FR", c1, c2, c3)

    def eDIP_RE(self,n1, n2):			
        """
        #RE=Set frametype: 
        #RE n1,n2  (n1=1..255: set frame type; n2=frameangle 0=0; 1=90; 2=180; 3=270)
        """
        self.__eDIP_command2("RE", n1, n2)

    def eDIP_RR(self,x1,y1,x2,y2):	
        """
        #RR=Draw frame: 
        #RR xx1,yy1,xx2,yy2  (Draw a frame from xx1,yy1 to xx2,yy2)
        """
        return self.__eDIP_draw("RR", x1, y1, x2, y2)

    #-------------------------- Bitmap/Animation commands
    #-------------------------- Bitmap commands

    def eDIP_FU(self,fg,bg):	
        """
        #FU=Set bitmap color: 
        #FU fg,bg  (fg=foreground- bg=background-color for monochrome bitmaps; fg/bg=palette 1..32 or 0=transparent)
        """
        return self.__eDIP_command("FU", fg, bg) 

    def eDIP_UZ(self,x,y):	
        """
        #UZ=Image zoom factor: 
        #UZ n1,n2  (n1=X-Zoom factor 1x..8x;  n2=Y-Zoom factor 1x..8x)
        """
        return self.__eDIP_command("UZ", x, y)	

    def eDIP_UW(self,n1):		
        """
        #UW=Image angle: 
        #UW n1  (Image output angle n1: 0=0; 1=90; 2=180; 3=270)
        """
        return self.__eDIP_command("UW", n1)		

    def eDIP_UX(self,n1):		
        """
        #UX=Image mirror: 
        #UX n1  (mirror Image: n1=0 normal output; n1=1 mirror image horizontal)
        """	
        return self.__eDIP_command("UX", n1)		

    def eDIP_UT(self,n1):
        """
        #UT=Transparency bitmap color: 
        #UT n1 (n1=0 no transparency; n1=1 top left dot; n1=2 use defd color; n1=3 replace by background)
        """
        return self.__eDIP_command("UT", n1)		

    def eDIP_UI(self,x1,y1,nr):	
        """
        #UI=Load internal image: 
        #UI xx1,yy1,n1  (Load internal image number n1=0..255 from DATA-FLASH to xx1,yy1)
        """
        return self.__eDIP_draw("UI", x1, y1, nr) 

        #-------------------------- Animation coomands

        #-------------------------- Bargraph commands
    def eDIP_FB(self,fg,bg,fc):
        """
        #FB=Set bargraph color: 
        #FB fg,bg,fr  (fg=foreground color; bg=background color; fr=frame color; fg/bg/fr=palette 1..32)
        """
        return self.__eDIP_command("FB", fg, bg, fc) 

    def eDIP_BM(self,n1):
        """
        #BM=Bar pattern: 
        #BM n1  (n1=1..255: use a pattern for bartype 0..3; n1=0: no pattern, use foreground color)
        """
        return self.__eDIP_command("BM", n1) 

    def eDIP_BE(self,n1):
        """
        #BE=Bar frametype: 
        #BE n1  (n1=1..255: set a frame for bartype 4..7)
        """
        return self.__eDIP_command("BE", n1) 

    def eDIP_BB(self,n1):
        """
        #BB=Bar dotwidth: 
        #BB n1  (n1=1..255: for dot with pattern bartype 2+3; n1=16..255: for dot with frame bartype 6+7; n1=0:automatic)
        """
        return self.__eDIP_command("BB", n1) 

    def eDIP_BR(self,nr,x1,y1,x2,y2,sv,ev,type):
        """
        #BR=Bar Right: 
        #BR n1,xx1,yy1,xx2,yy2,sv,ev,typ  (n1=1..20; xx1..yy2=rectangle; sv,ev=start/end value; typ:0..7)
        """
        return self.__eDIP_bargraph("BR", nr, x1, y1, x2, y2, sv, ev, type)

    def eDIP_BL(self,nr,x1,y1,x2,y2,sv,ev,type):
        """
        #BL=Bar Left: 
        #BL n1,xx1,yy1,xx2,yy2,sv,ev,typ  (n1=1..20; xx1..yy2=rectangle; sv,ev=start/end value; typ:0..7)
        """
        return self.__eDIP_bargraph("BL", nr, x1, y1, x2, y2, sv, ev, type)

    def eDIP_BO(self,nr,x1,y1,x2,y2,sv,ev,type):
        """
        #BO=Bar Up: 
        #BO n1,xx1,yy1,xx2,yy2,sv,ev,typ  (n1=1..20; xx1..yy2=rectangle; sv,ev=start/end value; typ:0..7)
        """
        return self.__eDIP_bargraph("BO", nr, x1, y1, x2, y2, sv, ev, type)

    def eDIP_BU(self,nr,x1,y1,x2,y2,sv,ev,type):
        """
        #BU=Bar Down: 
        #BU n1,xx1,yy1,xx2,yy2,sv,ev,typ  (n1=1..20; xx1..yy2=rectangle; sv,ev=start/end value; typ:0..7)
        """
        return self.__eDIP_bargraph("BU", nr, x1, y1, x2, y2, sv, ev, type)

    def eDIP_BA(self,n1, val):
        """
        #BA=Update Bargraph: 
        #BA n1,n2  (Set and draw the bar graph with the number n1 to the new user value n2)
        """
        return self.__eDIP_command("BA", n1, val)	

    def eDIP_BN(self,no):
        """
        #BN=Draw new Bargraph: #BN n1  (Draw the bar graph with the number n1 completely)
        """
        return self.__eDIP_command("BN", no)			

    def eDIP_BS(self,no):
        """
        #BS=Send Bargraph value: 
        #BS n1  (Send the current value of bargraph n1 on the serial interface)
        """
        return self.__eDIP_command("BS", no)

    def eDIP_BD(self,no, n2):
        """
        #BD=Delete Bargraph: 
        #BD n1,n2  (Makes definition of bar n1 invalid. n2=0: bar keeps visible; n2=1: bar will be cleared)
        """
        return self.__eDIP_command("BD", no, n2)


    #---------------------------- Macro instructions
    #---------------------------- Macro commands

    def eDIP_MN(self,no):
        """
        #MN=Run macro: 
        #MN n1  (Call the macro with the number n1=0..255; max. 7 levels)
        """
        return self.__eDIP_command("MN", no) 

    def eDIP_MT(self,no):
        """
        #MT=Run touch macro: 
        #MT n1  (Call the touch-macro with the number n1=0..255; max. 7 levels)
        """
        return self.__eDIP_command1("MT", no)

    def eDIP_MP(self,no):
        """
        #MP=Run port macro: 
        #MP n1  (Call the port-macro with the number n1=0..255; max. 7 levels)
        """
        return self.__eDIP_command("MP", no)

    def eDIP_MB(self,no):
        """
        #MB=Run bit macro: 
        #MB n1  (Call the bit-macro with the number n1=0..255; max. 7 levels)
        """
        return self.__eDIP_command("MB", no)

    def eDIP_MX(self,no):
        """
        #MX=Run matrix macro: 
        #MX n1  (Call the matrix-macro with the number n1=0..255; max. 7 levels)
        """
        return self.__eDIP_command("MX", no)

    def eDIP_MC(self,no):
        """
        #MC=Run process macro: 
        #MC n1  (Call the process-macro with the number n1=0..255; max. 7 levels)
        """
        return self.__eDIP_command("MC", no)	

    def eDIP_MV(self,no):
        """
        #MV=Run anlog macro: 
        #MV n1  (Call the analog-macro with the number n1=0..255; max. 7 levels)
        """
        return self.__eDIP_command("MV", no)	

    def eDIP_ML(self,type,n1,n2):
        """
        #ML=Inhibit macro: 
        #ML type,n1,n2  (Inhibit execution for macro type='N,T,M,P,B,X,C' or 'A'=all types from macro number n1 to n2)
        """
        return self.__eDIP_command("ML", type, n1, n2)

    def eDIP_MU(self,type,n1,n2):
        """
        #MU=Enable macro: 
        #MU type,n1,n2  (Enables execution for macro type='N,T,M,P,B,X,C' or 'A'=all types from macro number n1 to n2)
        """
        return self.__eDIP_command("MU", type, n1, n2) 

    def eDIP_MK(self,n1):
        """
        #MK=Select page: 
        #MK n1  (Select pagenumber n1=0..15 for macros/pictures)
        """
        return self.__eDIP_command("MK", n1)	

    def eDIP_MW(self):
        """
        #MW=Save page: 
        #MW  (Save actually macros/pictures pagenumber)
        """
        return self.__eDIP_command("MW")	

    def eDIP_MR(self):
        """
        #MR=Restore page: 
        #MR  (Restore last macros/pictures pagenumber)
        """
        return self.__eDIP_command("MR")	

    #   //automatic (normal-) macro

    def eDIP_MG(self,n1, n2):
        """
        #MG=Macro with delay: 
        #MG n1,n2  (macro n1=0..255 runs after delay of n2/10s. May be stopped/prevented by any command)
        """
        return self.__eDIP_command("MG", n1, n2)	 

    def eDIP_ME(self,n1,n2,n3):
        """
        #ME=Autom. macro once: 
        #ME n1,n2,n3  (Automatic once only macros n1..n2; n3=pause in 1/10s. Will be stopped by any command)
        """
        return self.__eDIP_command("ME", n1, n2, n3)

    def eDIP_MA(self,n1,n2,n3):
        """
        #MA=Autom. macro cyclical: 
        #MA n1,n2,n3  (Automatic cyclically macros n1..n2; n3=pause in 1/10s. Will be stopped by any command)
        """
        return self.__eDIP_command("MA", n1, n2, n3)

    def eDIP_MJ(self,n1,n2,n3):
        """
        #MJ=Autom. macro pingpong: 
        #MJ n1,n2,n3  (Automatic pingpong macros n1..n2..n1; n3=pause in 1/10s. Will be stopped by any command)
        """
        return self.__eDIP_command("MJ", n1, n2, n3)
#			//macro processes
    def eDIP_MD(self,no,type,n3,n4,zs):
        """
        #MD=def process macro: 
        #MD n1,typ,n3,n4,n5  (macro process n1=1..4; typ: 1=once; 2=cyclical; 3=pingpong; n3..n4=range; n5=delay)
        """
        return self.__eDIP_command("MD", no, type, n3, n4, zs)

    def eDIP_MZ(self,n1, zs):
        """
        #MZ=Process macro speed: 
        #MZ n1,n2  (Assign a new delay for process n1=1..4 with n2/10s. n2=0 will stop the automatic)
        """
        return self.__eDIP_command("MZ", n1, zs)

    def eDIP_MS(self,n1):
        """
        #MS=Stop process/animation: 
        #MS n1  (All process macros/animations will be stopped with n1=0 and continued with n1=1)
        """
        return self.__eDIP_command("MS", n1)	  

        #	//Touch Panel
        #		//touch presets

    def eDIP_FE(self,n1,n2,n3,s1,s2,s3):
        """
        #FE=Set touchborder colors: 
        #FE n1,n2,n3,s1,s2,s3  (n1..n3=normal s1..s3=for selection (0..32); 1=frame outside;2=inside;3=filling)
        """
        return self.__eDIP_command("FE", n1, n2, n3, s1, s2, s3)

    def eDIP_AE(self,n1, n2):
        """
        #AE=Touch frame: 
        #AE n1,n2  (n1=1..255: frame type for touch keys/switches; n1=0:no frame; n2=frameangle 0=0;1=90;2=180;3=270)
        """
        return self.__eDIP_command("AE", n1, n2)		  

    def eDIP_FC(self,nf,nb,sf,sb):
        """
        #FC=Set touchbutton colors: 
        #FC nf,nb,sf,sb  (monochrome: n.=normal; s.=for selection .f=foreground-; .b=background-color 0..32)
        """
        return self.__eDIP_command("FC", nf, nb, sf, sb)

    def eDIP_AC(self,n1,n2,n3,n4):
        """
        #AC=Touch button: 
        #AC n1,n2,n3,n4  (button number n1=0..255; n2=angle 0=0;1=90;2=180;3=270; n1=X-zoom 1x..8x; n2=Y-zoom 1x..8x)
        """	
        return self.__eDIP_command("AC", n1, n2, n3, n4)

    def eDIP_AR(self,no):
        """
        #AR=def radiogroup: 
        #AR n1  (n1=1..255: next switch definitions will join to group n1; n1=0 next def. are free of all groups)
        """
        return self.__eDIP_command("AR", no)	

        #label font presets

    def eDIP_FA(self,nf, sf):
        """
        #FA=Set touchstring color: 
        #FA n1,s2  (n1=normal textcolor; s2=textcolor for selection; n1/s2=palette 1..32)
        """
        return self.__eDIP_command("FA", nf, sf)	

    def eDIP_AF(self,no):
        """
        #AF=Touchlabel font: 
        #AF n1  (Set font with the number n1=0..255 for touch key label)
        """
        return self.__eDIP_command("AF", no)	

    def eDIP_AZ(self,x, y):
        """
        #AZ=Touchlabel zoom: 
        #AZ n1,n2  (n1=X-zoom factor 1x..8x; n2=Y-zoom factor 1x..8x)
        """
        return self.__eDIP_command("AZ", x, y)

    def eDIP_AY(self,x, y):
        """
        #AY=Touchlabel char width/height: 
        #AY n1,n2  (adds n1=0..15 dots at left/right and n2=0..15 dots at top/bottom of each character)
        """
        return self.__eDIP_command("AY", x, y)	

    def eDIP_AW(self,n1):
        """
        #AW=Touchlabel angle: 
        #AW n1  (Touchtext output angle n1: 0=0; 1=90; 2=180; 3=270)
        """
        return self.__eDIP_command("AW", n1)	

    def eDIP_AO(self,n1, n2):
        """
        #AO=Touchlabel offset for selection: 
        #AO n1,n2  (n1=X-offset; n2=Y-offset; n1,n2=0..7 +8 for negative direction)
        """
        return self.__eDIP_command("AO", n1, n2)	
#			//def touch areas
    def eDIP_AT(self,x1,y1,x2,y2,dc,uc,string):
        """
        #AT=def touch key: 
        #AT xx1,yy1,xx2,yy2,down,up,"text"  (xx1,yy1,xx2,yy2=rectangle; down:ONcode; up:OFFcode; down/up=0 ignore)
        """
        return self.__eDIP_touch("AT", string, dc, uc, x1, y1, x2, y2)	

    def eDIP_AU(self,x1,y1,dc,uc,string):
        """
        #AU=def touch key: 
        #AU xx1,yy1,down,up,"text"  (actually button at xx1,yy2; down:presscode; up:releasecode; down/up=0 ignore)
        """
        return self.__eDIP_touch("AU", string , dc, uc, x1, y1)		

    def eDIP_AK(self,x1,y1,x2,y2,dc,uc,string):
        """
        #AK=def touch switch: 
        #AK xx1,yy1,xx2,yy2,down,up,"text"  (xx1,yy1,xx2,yy2=rectangle; down:ONcode; up:OFFcode; down/up=0 ignore)
        """
        return self.__eDIP_touch("AK", string, dc, uc, x1, y1, x2, y2)

    def eDIP_AJ(self,x1,y1,dc,uc,string):
        """
        #AJ=def touch switch: 
        #AJ xx1,yy1,down,up,"text"  (actually button xx1,yy2; down: ON code; up: OFF code; down/up=0 ignore)
        """
        return self.__eDIP_touch("AJ", string, dc, uc, x1, y1)	

    def eDIP_AD(self,x1,y1,x2,y2,n1,fg):
        """
        #AD=def drawing area: 
        AD xx1,yy1,xx2,yy2,n1,fg  (Draw with a linewidth n1=1..15 and color fg=1..32 within xx1,yy1<->xx2,yy2)
        """
        return self.__eDIP_draw("AD", x1, y1, x2, y2, ((fg<<8)&0xFF00)+(n1&0x00FF))

    def eDIP_AH(self,x1,y1,x2,y2):
        """
        #AH=def free touch area: 
        #AH xx1,yy1,xx2,yy2  (Actions down,up,drag within the rectangle xx1,yy1<->xx2,yy2 are sent)
        """
        return self.__eDIP_draw("AH", x1, y1, x2, y2)

    def eDIP_AB(self,n1):
        """
        #AB=Set bargraph by touch: 
        #AB n1  (The bargraph with the n1=1..20 is defd for input by touch panel)
        """
        return self.__eDIP_command("AB", n1)

    def eDIP_APl(self,n1):
        """
        #A+=Set instrument by touch: 
        #A+ n1  (The instrument with the n1=1..4 is defd for input by touch panel)
        """
        return self.__eDIP_command("A+", n1)

#			//global settings

    def eDIP_AA(self,n1):
        """
        #AA=Touch query on/off: 
        #AA n1  (n1=0 Touch query is deactivated or n1=1 activated)
        """
        return self.__eDIP_command("AA", n1)	

    def eDIP_AI(self,n1):
        """
        #AI=Touch key inverse: 
        #AI n1  (Automatic inversion when touch key touched: n1=0=OFF; n1=1=ON)
        """
        return self.__eDIP_command("AI", n1)

    def eDIP_AS(self,n1):
        """
        #AS=Touch key buzzer: 
        #AS n1  (beeper output is going on when a touch key is touched: n1=0=OFF; n1=1=ON)
        """
        return self.__eDIP_command("AS", n1)	

    def eDIP_AQ(self,n1):
        """
        #AQ=Send bar value: 
        #AQ n1  (n1=0 Transmission of a new bar value is deactivated; n1=1 activated; n1=2 continous send)
        """
        return self.__eDIP_command("AQ", n1) 

    #   //other functions

    def eDIP_AN(self,code):
        """
        #AN=Invert touch key: 
        #AN code  (The touch key with the assigned by code is inverted manually)
        """
        return self.__eDIP_command("AN", code)	

    def eDIP_AP(self,code,n1):
        """
        #AP=Set touch switch: 
        #AP code,n1  (The status of the switch is changed by means of a command n1=0=off; n1=1=on)
        """
        return self.__eDIP_command("AP", code, n1) 

    def eDIP_AX(self,code):
        """
        #AX=Query touch switch: 
        #AX code  (The status of the switch off=0 on=1 is sent via the serial interface)
        """
        return self.__eDIP_command("AX", code)	

    def eDIP_AG(self,n1):
        """
        #AG=Query radiogroup: 
        #AG n1  (The code of activ switch in radiogroup n1 is sent via the serial interface)
        """
        return self.__eDIP_command("AG", n1)	

    def eDIP_AL(self,code,n1):
        """
        #AL=Delete touch area: 
        #AL code,n1  (Remove area from query; code=1..255; 0: all areas; n1: 0=area remains visible; 1=delete area)
        """
        return self.__eDIP_command("AL", code, n1) 

    def eDIP_AV(self,x1,y1,n1):
        """
        #AV=Delete touch area: 
        #AV xx1,yy1,n1  (Remove area witch includes point xx1,yy1 from query; n1:0=area remains visible; 1=del.area)
        """
        return self.__eDIP_draw("AV", x1, y1, n1) 


    # Commands for backlight, I/O-Port and misc
    # Backlight

    def eDIP_YH(self, n1):
        """
        #YH=Backlight brightness: 
        #YH n1  (Adjust brightness of backlight n1=0..100% non linear)
        """
        return self.__eDIP_command("YH", n1)	

    def eDIP_YN(self):
        """
        #YN=next backlight brightness: 
        #YN  (increase the brightness of the backlight)
        """
        return self.__eDIP_command("YN")	

    def eDIP_YP(self):
        """
        #YP=previous backlight brightness: 
        #YP  (decrease the brightness of the backlight)
        """
        return self.__eDIP_command("YP")		

    def eDIP_YZ(self,n1):
        """
        #YZ=brightness changetime: 
        #YZ n1  (n1=0..31 time in 1/10s for changing brightness of the backlight from 0 to 100%)
        """
        return self.__eDIP_command("YZ", n1)

    def eDIP_YL(self,n1):
        """
        #YL=Backlight on/off: 
        #YL n1  (LED backlight n1: 0=OFF; 1=ON; 2..255=switches backlight for n1/10s on and then off)
        """
        return self.__eDIP_command("YL", n1)

    def eDIP_YB(self, no):
        """
        #YB=assign bar with backlight: 
        #YB n1  (assign bar n1=1..20 for changing brightness of the backlight)
        """
        return self.__eDIP_command("YB", no)

    def eDIP_YPl(self, no):
        """
        #Y+=assign instrument with backlight: 
        #Y+ n1  (assign instrument n1=1..4 for changing brightness of the backlight)
        """
        return self.__eDIP_command("Y+", no)

    def eDIP_YAt(self):
        """
        #Y@=Save backlight parameter: 
        #Y@  (Save backlight start-brightness/-time in internal EEPROM)
        """
        return self.__eDIP_command("Y@")	

    #   //port commands

    def eDIP_YW(self,n1,n2):
        """
        #YW=Write output port: 
        #YW n1,n2  (n1=0: Set all ports to n2=8-bit binary value; n1=1..8: n2=0 Reset; n2=1 Set; n2=2 Invert port)
        """
        return self.__eDIP_command("YW", n1, n2)

    def eDIP_YR(self,n1):
        """
        #YR=Read input port: 
        #YR n1  (n1=0: Read all ports as 8-bit binary value; n1=1..8: Read port n1 and return 0 or 1)
        """
        return self.__eDIP_command("YR", n1)	

    def eDIP_YA(self,n1):
        """
        #YA=Port scan on/off: 
        #YA n1  (The automatic scan of the input port is n1=0: deactivated; n1=1: activated)
        """
        return self.__eDIP_command("YA", n1)	

    def eDIP_YI(self,n1):
        """
        #YI=Invert input port: 
        #YI n1  (The input port is n1=0: normal; n1=1: evaluated inverted)
        """
        return self.__eDIP_command("YI", n1)	

    def eDIP_YM(self,n1,n2,n3):
        """
        #YM=Matrix keyboard: 
        #YM n1,n2,n3  (Specifies a matrix keyboard. n1=number of inputs 1..8; n2=outputs 0..8; n3=debouncing 0..7)
        """
        return self.__eDIP_command("YM", n1, n2, n3)	

    def eDIP_YD(self,n1,n2,n3):
        """
        #YD=Redef input Bitmacro: 
        #YD n1,n2,n3  (input port n1=1..8; falling-/rising- edge n2=0/1; new BitMacro number n3=0..255)
        """
        return self.__eDIP_command("YD", n1, n2, n3)	

    def eDIP_YX(self,n1,n2):
        """
        #YX=Redef Matrixmacro: 
        #YX n1,n2  (assign matrix keynumber n1=0..65 with new MatrixMacro number n2=0..255)
        """
        return self.__eDIP_command("YX", n1, n2)	
#			//other commands
    def eDIP_FP(self,no,R5,G5,B5):
        """
        #FP=Set color palette: 
        #FP n1,r,g,b  (palette entry n1=1..32; r=red valid bits7..3; g=green valid bits7..2; b=blue valid bits7..3)
        """
        return self.__eDIP_command("FP", no, R5, G5, B5) 

    def eDIP_YS(self, n1):
        """
        #YS=Beep on/off: 
        #YS n1  (Switch beeper output n1=2..255 for n1/10s to high; n1=0 set permanent low; n1=1 set permanent high)
        """
        return self.__eDIP_command("YS", n1)	


    def eDIP_SV(self):
        """
        #SV=Send version: 
        #SV  (Software version will be sent as a string e.g. "EA eDIPTFT43-A V1.0 Rev.A")
        """
        return self.__eDIP_command("SV")		

    def request_Protocol_Settings(self):
        """
        This command is used to query protocol settings.
        """
        buffer = bytearray()
        buffer.append("P")
        return self.send_Command(buffer, protocol=True)

    def request_Content_Buffer(self):
        """
        Empties the display send buffer,
        the display replays with the ack and then begins to send
        all the collected data such as touch keystrokes.
        """
        buffer = bytearray()
        buffer.append("S")
        return self.send_Command(buffer, payload=True, protocol=True)

    #----------------------------------------------------------------------
    def request_Information_Buffer(self):
        """
        This command queries whether user data is ready to
        to be picked up an how full the display s receive buffer is
        """
        buffer = bytearray()
        buffer.append("I")
        return self.send_Command(buffer, payload=True, protocol=True)

    #----------------------------------------------------------------------
    def repeat_Last_Package(self):
        """
        if the most recently requested package contains an incorrect checksum
        the entire package can be requested again. the reply can then be the contents
        of the send buffer (<DC1>)or the buffer/protocol information (<DC2>)
        """
        buffer = bytearray()
        buffer.append("R")
        return self.send_Command(buffer, payload=True, protocol=True)

    #----------------------------------------------------------------------
    def protocol_Settings(self, pck_size, timeout):
        """
        This is how the maximum package size that can be sent by the display
        can be limited. The default setting is a package size with up to 128 bytes
        of user data.
        the timeout can be set in increments of 1/100 seconds
        The timeout is activated when individual bytes get lost. The entire
        package then has to be sent again.
        """
        buffer = bytearray()
        buffer.append("D")
        if(pck_size<1 or pck_size>128):
            raise Exception("Packet size out of range [1..128]")

        if(timeout<1 or timeout>255):
            raise Exception("Timeout out of range [1.255]")

        buffer.append(pck_size)
        buffer.append(timeout)
        return self.send_Command(buffer, protocol=True)        


